﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TA.DotNetUtils;
using System.Web.UI;

namespace TA.Turbo.Controls
{
	public class GroupedRepeaterRenderedItemsContainer : RepeaterRenderedItemsContainer
	{
		internal GroupedRepeaterRenderedItemsContainer(GroupedRepeater owner)
			: base(owner)
		{
		}
		public GroupedRepeater GroupedRepeater
		{
			get
			{
				return this.Repeater as GroupedRepeater;
			}
		}
		protected override void DoRender(System.Web.UI.HtmlTextWriter writer, MultipleInstanceTemplate t)
		{
			if (this.GroupedRepeater.Groupings.Count > 0)
			{
				// group of ints because ints are for the entry indexes
				List<EntryGroup<int>> groups = new List<EntryGroup<int>>();
				IRepeaterEntries entries = this.Repeater.Value.Entries;
				for (int iEntry = 0; iEntry < entries.Count; ++iEntry)
				{
					this.DoGroup(groups, iEntry, 0);
				}

				int nEntries = 0;
				this.DoRender(writer, t, groups, 0, ref nEntries);
			}
			else
			{
				base.DoRender(writer, t);
			}

		}
		private void DoGroup(List<EntryGroup<int>> groups, int iEntry, int iGrouping)
		{
			RepeaterGrouping grouping = this.GroupedRepeater.Groupings[iGrouping];

			EntryGroup<int> existing = this.DoGroup_FindExisting(groups, iEntry, grouping);

			if (existing == null)
			{
				existing = new EntryGroup<int>();
				groups.Add(existing);
			}

			existing.Entries.Add(iEntry);

			if (iGrouping < this.GroupedRepeater.Groupings.Count - 1)
			{
				DoGroup(existing.SubGroups, iEntry, iGrouping + 1);
			}
		}
		private EntryGroup<int> DoGroup_FindExisting(List<EntryGroup<int>> groups, int iEntry, RepeaterGrouping grouping)
		{
			EntryGroup<int> existing = null;

			foreach (EntryGroup<int> g in groups)
			{
				int oExisting = g.Entries[0];

				if (grouping.EntriesEqual(this.Entries, iEntry, oExisting))
				{
					existing = g;
					break;
				}
			}

			return existing;
		}
		private void DoRender(HtmlTextWriter writer, MultipleInstanceTemplate itemTemplate, List<EntryGroup<int>> groups, int iGrouping, ref int nEntries)
		{
			RepeaterGrouping grouping = this.GroupedRepeater.Groupings[iGrouping];

			for (int iGroup = 0; iGroup < groups.Count; ++iGroup)
			{
				EntryGroup<int> group = groups[iGroup];
				grouping.DoBind(this.Entries, iGroup, group);

				grouping.Header.Render(writer, grouping.Header.Container.ID + TControl.UniqueIdSeparator + iGroup);

				if (iGrouping < this.GroupedRepeater.Groupings.Count - 1)
				{
					this.DoRender(writer, itemTemplate, group.SubGroups, iGrouping + 1, ref nEntries);
				}
				else
				{
					foreach (object o in group.Entries)
					{
						this.Repeater.OnBindItem(new BindEventArgs(itemTemplate.Container, o));
						itemTemplate.Render(writer, nEntries.ToString());

						++nEntries;
					}
				}

				grouping.Footer.Render(writer, grouping.Footer.Container.ID + TControl.UniqueIdSeparator + iGroup);
			}
		}

	}
}
